import { createRef, RefObject } from 'react'
import type { Result } from 'ahooks/lib/useRequest/src/types'
import { create } from 'zustand'
import { AgGridReact } from '@ag-grid-community/react'

import { DEFAULT_PAGE_SIZE } from '@/utils/pagination'
import { apiGetEventTemplateTabCount } from './apis'
import { IEventTemplateItem, IEventTemplateReq, IEventTemplateRes, IEventTemplateTabCountRes } from './interface'
import { normalizeReqData } from './utils'

export type TRequest = Result<IEventTemplateRes, [IEventTemplateReq]>

export interface IStore {
  gridRef: RefObject<AgGridReact<IEventTemplateItem>>
  request?: TRequest
  reqData: IEventTemplateReq
  setReqData: (val: Partial<IEventTemplateReq> | ((prevVal: IEventTemplateReq) => IEventTemplateReq)) => void
  getData: (scrollToTop?: boolean) => void
  // Tab Count 状态与方法
  tabCountLoading: boolean
  tabCount: IEventTemplateTabCountRes[]
  getTabCount: (req: IEventTemplateReq) => void
}

export const defaultParams: IEventTemplateReq = {
  page: 1,
  size: DEFAULT_PAGE_SIZE,
  searchWord: undefined,
  shipTrackRequire: undefined,
  statusGroup: undefined,
  visibleFlag: undefined,
  messageType: undefined,
  tabId: 0,
}

// AbortController（TabCount 专用）
let tabCountController: AbortController | null = null

export const useBoundStore = create<IStore>((set, get) => {
  return {
    gridRef: createRef(),
    reqData: { ...defaultParams },
    setReqData: val => {
      set(prev => {
        return {
          reqData: {
            ...prev.reqData,
            ...(typeof val === 'function' ? val(prev.reqData) : val),
          },
        }
      })
    },
    getData: scrollToTop => {
      const { gridRef, request, reqData, getTabCount } = get()
      getTabCount(reqData)
      request?.run(normalizeReqData(reqData))
      if (scrollToTop) gridRef.current?.api?.ensureIndexVisible(0, 'top')
    },
    // 初始化 TabCount
    tabCountLoading: false,
    tabCount: [],

    // 拉取 TabCount
    getTabCount: (req: IEventTemplateReq) => {
      const { tabCountLoading } = get()
      if (tabCountLoading) return

      tabCountController?.abort()
      tabCountController = new AbortController()

      set({ tabCountLoading: true })
      apiGetEventTemplateTabCount(req, tabCountController.signal)
        .then(data => {
          set({ tabCountLoading: false, tabCount: data || null })
        })
        .catch(() => {
          set({ tabCountLoading: false })
        })
    },
  }
})
